#pragma once

#include "list.h"

template<typename first, typename second, int carry>
struct substraction_reversed
{
   typedef list_t<
      (first::head_ + second::head_ + carry) % BASE,
      typename substraction_reversed<
         typename first::tail_,
         typename second::tail_,
         (first::head_ + second::head_ + carry) / BASE
      >::result_
   > result_;
};

template<typename first, int carry>
struct substraction_reversed<first, empty_list_t, carry>
{
   typedef list_t<
      (first::head_ + 0 + carry) % BASE,
      typename substraction_reversed<
         typename first::tail_,
         empty_list_t,
         (first::head_ + 0 + carry) / BASE
      >::result_
   > result_;
};

template<typename second, int carry>
struct substraction_reversed<empty_list_t, second, carry>
{
   typedef list_t<
      (0 + second::head_ + carry) % BASE,
      typename substraction_reversed<
         empty_list_t,
         typename second::tail_,
         (0 + second::head_ + carry) / BASE
      >::result_
   > result_;
};

template<int carry>
struct substraction_reversed<empty_list_t, empty_list_t, carry>
{
   typedef list_t<
      (0 + 0 + carry) % BASE,
      typename substraction_reversed<
         empty_list_t,
         empty_list_t,
         (0 + 0 + carry) / BASE
      >::result_
   > result_;
};

template<>
struct substraction_reversed<empty_list_t, empty_list_t, 0>
{
   typedef empty_list_t result_;
};

template<typename first, typename second>
struct substraction
{
   typedef typename reverse<
      typename substraction_reversed<
         typename reverse<first>::result_,
         typename reverse<second>::result_,
         0
      >::result_
   >::result_ result_;
};